﻿#region copyright info
//------------------------------------------------------------------------------
// <copyright company="ChaosStudio">
//     Copyright (c) 2002-2010 巧思工作室.  All rights reserved.
//     Contact:		MSN:zhouyu@cszi.com , QQ:478779122
//		Link:				http://www.69sea.com http://www.cszi.com
// </copyright>
//------------------------------------------------------------------------------
#endregion

using System;
using System.ComponentModel;
using System.Configuration.Install;
using System.Reflection;
using System.ServiceProcess;
using System.Threading;
using CS.Cryptography;
using log4net;
using CS.WinService;

namespace WinService
{
    /// <summary>
    /// 基于CS.Scheduling.Framework[v1.31] 架构的Windwos服务示例
    /// <remarks>
    /// 1. 暂不支持暂停恢复功能
    /// </remarks>
    /// <description>
    /// zhouyu 2010.3.10 created.
    /// zhouyu 2010.5.19 update.
    /// zhouyu 2010-5-31 支持暂停，恢复功能。
    /// </description>
    /// </summary>
    public class TaskService : ServiceBase
    {
        /// <summary>
        /// 服务管理器
        /// </summary>
        private Task4WinService _taskService;
        /// <summary>
        /// 运行日志
        /// </summary>
        private static readonly ILog logRun = LogManager.GetLogger(typeof(TaskService));

        #region 应用程序入口

        /// <summary>
        /// 应用程序入口
        /// </summary>
        /// <param name="args"></param>
        public static void Main(string[] args)
        {

            try
            {
                var newMutexCreated = false;
                //var reg = new Regex("[^A-Za-z0-9_]", RegexOptions.Compiled);    //移去非字符数字的字符
                var mutexName = Md5.Encrypt(String.Format("{0}-{1}", AppDomain.CurrentDomain.BaseDirectory, Assembly.GetExecutingAssembly().GetName().FullName)); //唯一的名称

                try
                {
                    new Mutex(false, mutexName, out newMutexCreated);
                }
                catch (Exception ex)
                {
                    logRun.Error(string.Format("创建互斥体[mutexName = {0}]异常，程序退出", mutexName), ex);
                    Environment.Exit(1);
                }
                if (newMutexCreated)
                {
                    logRun.DebugFormat("创建互斥体[mutexName = {0}]成功，开始创建服务", mutexName);
                    var service = new TaskService();
                    var paramLength = args != null ? args.Length : 0;  //参数长度

                    if (paramLength > 0) //有参数时以 console 方式运行
                    {
                        logRun.Info("------ Run as Console ------");
                        service.OnStart(null);
                        Console.ReadLine();
                    }
                    else
                    {
                        logRun.Info("------ Run as WindowsService ------");
                        Run(service);
                    }
                }
                else
                {
                    logRun.Error("有一个实例正在运行，如要调试，请先停止其它正在运行的实例如WindowsService，程序退出。");
                    Environment.Exit(1);
                }
            }
            catch (Exception ex)
            {
                logRun.Error("启动服务异常", ex);
                throw;
            }
        }

        #endregion


        /// <summary>
        /// 默认构造，相关初始化
        /// </summary>
        public TaskService()
        {
            CanPauseAndContinue = true;
            ServiceName = ConfigInfo.ServiceName;
            logRun.DebugFormat("服务类初始化完成");
        }


        #region Start & Stop  &   Pause & Continue

        /// <summary>
        /// 启动服务
        /// </summary>
        /// <param name="args"></param>
        protected override void OnStart(string[] args)
        {
           
            try
            {
                if (_taskService == null)
                    _taskService = new Task4WinService();
                logRun.InfoFormat("try run the {0}.", ConfigInfo.DisplayName);
                _taskService.Start();
                logRun.InfoFormat("{0} is runing.", ConfigInfo.DisplayName);
            }
            catch (Exception ex)
            {
                logRun.FatalFormat("启动服务时发生异常",ex);
                throw;
            }
        }

        /// <summary>
        /// 停止服务
        /// </summary>
        protected override void OnStop()
        {
            logRun.InfoFormat("try stop the {0}.", ConfigInfo.DisplayName);
            _taskService.Stop();
            logRun.InfoFormat("{0} is stoped.", ConfigInfo.DisplayName);
        }

        /// <summary>
        /// 暂停
        /// </summary>
        protected override void OnPause()
        {
            logRun.InfoFormat("try pause the {0}", ConfigInfo.DisplayName);
            _taskService.Pause();
            logRun.InfoFormat("{0} is pauseed\n", ConfigInfo.DisplayName);
        }

        /// <summary>
        /// 继续执行
        /// </summary>
        protected override void OnContinue()
        {
            logRun.InfoFormat("try continue the {0}", ConfigInfo.DisplayName);
            _taskService.Resume();
            logRun.InfoFormat("{0} is continued\n", ConfigInfo.DisplayName);
        }

        

        #endregion

    }


    #region 服务安装配置

    /// <summary>
    /// 安装服务
    /// </summary>
    [RunInstaller(true)]
    public class ProjectInstaller : Installer
    {
        private readonly ServiceInstaller _serviceInstaller;
        private readonly ServiceProcessInstaller _processInstaller;

        public ProjectInstaller()
        {
            _processInstaller = new ServiceProcessInstaller();
            _serviceInstaller = new ServiceInstaller();

            // 以系统账户身份运行
            _processInstaller.Account = ServiceAccount.LocalSystem;

            // 自动启动服务，手动的话，每次开机都要手动启动。
            _serviceInstaller.StartType = ServiceStartMode.Automatic;

            //服务信息
            _serviceInstaller.ServiceName = ConfigInfo.ServiceName;
            _serviceInstaller.DisplayName = ConfigInfo.DisplayName;
            _serviceInstaller.Description = ConfigInfo.Description;
            

            Installers.Add(_serviceInstaller);
            Installers.Add(_processInstaller);
        }
    }

    #endregion

}